package org.freecode.irc.votebot;
import org.freecode.irc.votebot.api.ExternalModule;
import org.freecode.irc.votebot.modules.admin.LoadModules;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;
import javax.script.ScriptException;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
/**
* Loads scripted modules for FreeVoteBot.
* Modules may be scripted in Jython
*
* @author Shivam Mistry
*/
public class ScriptModuleLoader {
private final FreeVoteBot fvb;
/**
* Initialises a ScriptModuleLoader
*
* @param fvb the instance of {@link FreeVoteBot} where the modules should be loaded to
*/
public ScriptModuleLoader(FreeVoteBot fvb) {
this.fvb = fvb;
Properties props = new Properties();
props.setProperty("python.path", new File(".", "target").getAbsolutePath()
+ ":" + LoadModules.MODULES_DIR.getAbsolutePath());
PythonInterpreter.initialize(System.getProperties(), props,
new String[]{""});
}
/**
* Loads a module from a Python file that contains a class with the <b>SAME</b> name as the file.
* The class must extend {@link ExternalModule}.
*
* @param f the file to load the {@link org.freecode.irc.votebot.api.ExternalModule} from
* @return the {@link ExternalModule} loaded, or <tt>null</tt>
* @throws IOException if the file was not found
* @throws ScriptException if the script failed to load
*/
public ExternalModule loadFromFile(final File f) throws IOException, ScriptException {
if (f == null || !f.exists()) {
throw new IOException("Invalid file");
}
if (f.getName().endsWith(".py")) {
PythonInterpreter interpreter = new PythonInterpreter();
String clzName = f.getName().replace(".py", "");
interpreter.exec(String.format("from %s import %s", clzName, clzName));
PyObject pyClass = interpreter.get(clzName);
PyObject buildObject = pyClass.__call__();
ExternalModule ext = (ExternalModule) buildObject.__tojava__(ExternalModule.class);
ext.setFvb(fvb);
ext.setExtName(clzName);
interpreter.cleanup();
return ext;
}
return null;
}
}